

extern alias JB;

namespace StyleCop.For.ReSharper.BulbItems.Framework
{
    #region Using Directives

    using System;
    using JetBrains.Application;
    using JetBrains.Application.Progress;
    using JetBrains.ProjectModel;
    using JetBrains.ReSharper.Psi;
    using JetBrains.TextControl;
    using JetBrains.DocumentModel;
    using JetBrains.ReSharper.Intentions;

    #endregion

    /// <summary>
    /// BulbItem Implementation for ReSharper 5.0 style build items.
    /// </summary>
    public abstract class V5BulbItemImpl : BulbItemImpl
    {
        #region Properties

        /// <summary>
        /// Gets or sets the description of the BulbItem.
        /// </summary> 
        public string Description { get; set; }

        /// <summary>Gets or sets the document range to be used by the BulbItem.</summary>
        /// <value>The document range.</value>
        public DocumentRange DocumentRange { get; set; }

        /// <summary>Gets or sets the current file name.</summary>
        /// <value>The file name.</value>
        public string FileName { get; set; }

        /// <summary>Gets or sets the line number to be used by the BulbItem.</summary>
        /// <value>The line number.</value>
        public int LineNumber { get; set; }

        /// <summary>Gets or sets the prefix spacing.</summary>
        /// <value>The prefix.</value>
        public string Prefix { get; set; }

        /// <summary>Gets or sets the suffix spacing.</summary>
        /// <value>The suffix.</value>
        public string Suffix { get; set; }

        /// <summary>Gets or sets a string to format spacing.</summary>
        /// <value>The target.</value>
        public string Target { get; set; }

        /// <summary>
        /// Gets the text to display in the Quick Fix bulb item.
        /// </summary>
        public override string Text
        {
            get { return this.Description; }
        }

        #endregion

        /// <summary>
        /// Performs the QuickFix, ensures the file is both writable and creates a transaction.
        /// </summary>
        /// <param name="solution">
        /// Current Solution.
        /// </param>
        /// <param name="progress">
        /// Progress Indicator for the fix.
        /// </param>
        /// <returns>
        /// The execute transaction.
        /// </returns>
        /// 
        protected override Action<ITextControl> ExecuteTransaction(ISolution solution, JB::JetBrains.Application.Progress.IProgressIndicator progress)
        {
            return delegate(ITextControl textControl)
            {
                using (DocumentManager.GetInstance(solution).EnsureWritable())
                {
                    PsiManager.GetInstance(solution).DoTransaction(() => this.ExecuteWriteLockableTransaction(solution, textControl));
                }
            };
        }

        /// <summary>
        /// Actual implementation of Quick Fix should happen within an overridden instance of this method.
        /// </summary>
        /// <param name="solution">Current Solution</param>
        /// <param name="textControl">Current Text Control</param>
        public abstract void ExecuteTransactionInner(ISolution solution, ITextControl textControl);

        /// <summary>
        /// Ensure that a WriteLockCookie has been created in the scope of the transaction.
        /// </summary>
        /// <param name="solution">Current Solution</param>
        /// <param name="textControl">Current Text Control</param>
        protected void ExecuteWriteLockableTransaction(ISolution solution, ITextControl textControl)
        {
            using (WriteLockCookie.Create(true))
            {
                this.ExecuteTransactionInner(solution, textControl);
            }
        }
    }
}